class Furniture:
    def __init__(self, name, area, age):  # 初始化对象属性
        self.name = name
        self.area = area
        self.__age = age  # 属性名前加__成为私有属性（只有自身类内的方法可以操作私有属性，在自身类外不可以直接操作）

    def __str__(self):  # 打印对象变量时返回的内容(对象的描述信息)
        return f"{self.name}占地面积为{self.area}"

    def __del__(self):  # 对象被销毁时（局部变量：函数执行结束时。全局变量：程序执行结束时。主动销毁时：del（））会执行下面代码
        print(f"{self.name}被销毁")

    def minish(self):
        self.area -= 2
        print(f"{self.name}减小了，面积为{self.area}")

    def __print_age(self):  # 方法名前加__成为私有方法（只有自身类内的方法可以调用私有方法，在自身类外不可以直接调用私有方法）
        print(f"{self.name}现在{self.__age}岁")

    def use_age(self):  # 操作私有属性，调用私有方法
        self.__print_age()
        self.__age += 1
        print(f"{self.name}长了1岁，现在{self.__age}岁")


class House:
    def __init__(self, name, area):
        self.name = name
        self.area = area
        self.furniture = []  # 定义一个对象时，某个属性不确定时可以不写入init形参要求传递

    def __str__(self):
        return f"{self.name}房子的家具有{self.furniture},剩余面积为{self.area}"

    # 方法的参数是另一对象时可加：类名（注解）帮助快速联想，此时可在此方法中通过这个对象参数调用这个对象的方法
    # 当init中的参数是另一对象时，调用这个对象参数的代码格式稍有不同：self.对象参数.方法（相当于此时这个对象参数是self的一个属性）
    def decorate(self, item: Furniture):
        if item.area < self.area:
            self.area -= item.area
            self.furniture.append(item)
            print(f"{self.name}房子装入了{item.name},剩余面积为{self.area}")
        else:
            item.minish()
            self.area -= item.area
            print(f"{item.name}面积缩小为{item.area},然后装入{self.name}房子")


def basic_class_object():  # 以上为类和对象的基本操作练习
    bed = Furniture("床", 4, 1)
    chest = Furniture("柜子", 4, 1)
    table = Furniture("桌子", 3, 1)
    table.use_age()
    house1 = House("木屋", 10)
    print(house1)
    house1.decorate(bed)
    house1.decorate(chest)
    house1.decorate(table)


if __name__ == '__main__':
    basic_class_object()
